﻿namespace EyeOpen.VisualStudio2005BackMigration.Windows
{
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Windows.Forms;

    public partial class Main : Form
    {
        private UpdateProgressDelegate updateProgressDelegate = delegate(ListBox listBox, ProgressBar progressBar, FileProcessedEventArgs e)
        {
            listBox.Items.Add(e.ProcessedFile.FullName);
            progressBar.Value = e.PartialProcessed;
            progressBar.Maximum = e.Total;
        };

        private UpdateCompletedDelegate updateCompletedDelegate = delegate(ListBox processListBox, MigrationService migrationService)
        {
            processListBox.Items.Add(string.Empty);
            processListBox.Items.Add("Solutions processed: " + migrationService.ProcessedSolutions);
            processListBox.Items.Add("Projects processed: " + migrationService.ProcessedProjects);
            processListBox.Items.Add("Source files processed: " + migrationService.ProcessedSource);
            processListBox.Items.Add("Total files processed: " + migrationService.TotalProcessed);

            MessageBox.Show("Conversion completed.", "Completed", MessageBoxButtons.OK, MessageBoxIcon.Information);
        };

        public Main()
        {
            this.InitializeComponent();
        }

        private delegate void UpdateProgressDelegate(ListBox listBox, ProgressBar progressBar, FileProcessedEventArgs e);

        private delegate void UpdateCompletedDelegate(ListBox processListBox, MigrationService migrationService);

        private delegate void MigrationServiceDelegate(string sourcePath, string destinationPath);

        private void ConvertLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (!this.ValidateFolder(this.sourceFolderTextBox))
            {
                return;
            }

            if (!this.ValidateFolder(this.destinationFolderTextBox))
            {
                return;
            }
            else
            {
                DirectoryInfo destionationFolder = new DirectoryInfo(this.destinationFolderTextBox.Text);
                if (destionationFolder.Exists)
                {
                    if (MessageBox.Show("Delete destination folder and all its contents?", "Delete destination folder", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button3) == DialogResult.Yes)
                    {
                        this.convertLinkLabel.Enabled = false;

                        IEnumerable<FileInfo> readOnlyFiles =
                            from file in destionationFolder.GetFiles("*.*", SearchOption.AllDirectories)
                            where (file.Attributes & FileAttributes.ReadOnly) != 0
                            select file;

                        readOnlyFiles.ToList().ForEach(file => file.Attributes = FileAttributes.Archive);
                        destionationFolder.Delete(true);
                    }
                    else
                    {
                        MessageBox.Show("Operation aborted.", "Aborted", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                }
            }
            
            this.convertLinkLabel.Enabled = false;
            this.processListBox.Items.Clear();

            MigrationService migrationService = new MigrationService();

            MigrationServiceDelegate migrationServiceDelegate = new MigrationServiceDelegate(migrationService.MigrateBack);
            if (!this.silentModeCheckBox.Checked)
            {
                migrationService.FileProcessed += new System.EventHandler<FileProcessedEventArgs>(this.MigrateService_FileProcessed);
            }

            migrationService.Completed += new System.EventHandler<System.EventArgs>(this.MigrateService_Completed);
            migrationServiceDelegate.BeginInvoke(this.sourceFolderTextBox.Text, this.destinationFolderTextBox.Text, null, null);

            this.convertLinkLabel.Enabled = true;
        }

        private void MigrateService_Completed(object sender, System.EventArgs e)
        {
            MigrationService migrationService = (MigrationService)sender;

            this.Invoke(this.updateCompletedDelegate, new object[] { this.processListBox, migrationService });
        }

        private void MigrateService_FileProcessed(object sender, FileProcessedEventArgs e)
        {
            this.BeginInvoke(this.updateProgressDelegate, new object[] { this.processListBox, this.processProgressBar, e });
        }

        private void SourceFolderTextBox_TextChanged(object sender, System.EventArgs e)
        {
            if (string.IsNullOrEmpty(this.destinationFolderTextBox.Text))
            {
                try
                {                       
                    DirectoryInfo directory = new DirectoryInfo(this.sourceFolderTextBox.Text);
                    this.destinationFolderTextBox.Text = this.sourceFolderTextBox.Text + ".Converted";
                }
                catch
                {
                }
            }
        }

        private void SourceLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this.ShowFolderDialog(this.sourceFolderTextBox);
        }

        private void DestinationLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this.ShowFolderDialog(this.destinationFolderTextBox);
        }

        /// <summary>
        /// Shows the folder dialog.
        /// </summary>
        /// <param name="textBox">The text box.</param>
        private void ShowFolderDialog(TextBox textBox)
        {
            FolderBrowserDialog folderDialog = new FolderBrowserDialog();
            folderDialog.ShowNewFolderButton = false;
            if (folderDialog.ShowDialog() == DialogResult.OK)
            {
                textBox.Text = folderDialog.SelectedPath;
            }
        }

        /// <summary>
        /// Validates the folder.
        /// </summary>
        /// <param name="textBox">The text box.</param>
        /// <returns></returns>
        private bool ValidateFolder(TextBox textBox)
        {
            try
            {
                new DirectoryInfo(textBox.Text);
                this.mainErrorProvider.SetError(textBox, null);
                return true;
            }
            catch
            {
                this.mainErrorProvider.SetError(textBox, "Directory not valid.");
                return false;
            }
        }
    }
}